package com.xqkj.commons.virtualdb.service.functions;

import com.xqkj.commons.virtualdb.model.VirtualDbAttributeLockInfoModel;
import com.xqkj.commons.virtualdb.model.VirtualDbLockInfoModel;
import com.xqkj.commons.virtualdb.model.VirtualDbLockResultModel;
import org.apache.commons.collections4.CollectionUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

/**
 * @author lwt<br>
 * @description <br>
 * @date 2020/1/15
 */
public class LockAllFunction implements Function<VirtualDbLockInfoModel,VirtualDbLockResultModel> {

    private Function<String,Boolean> lockFunction;

    public LockAllFunction(Function<String,Boolean> lockFunction){
        this.lockFunction=lockFunction;
    }

    @Override
    public VirtualDbLockResultModel apply(VirtualDbLockInfoModel virtualDbLockInfoModel) {
        VirtualDbLockResultModel lockResultModel=new VirtualDbLockResultModel();
        boolean isLockedMain=lockForOperate(virtualDbLockInfoModel.getMainIdxLockKey());
        virtualDbLockInfoModel.setMainIdxLocked(isLockedMain);
        if(!isLockedMain){
            return lockResultModel;
        }
        //
        List<VirtualDbAttributeLockInfoModel> attributeLockInfolList=virtualDbLockInfoModel.getAttributeLockInfolList();
        if(CollectionUtils.isEmpty(attributeLockInfolList)){
            return lockResultModel;
        }
        Map<String,Boolean> lockResultMap = virtualDbLockInfoModel.getAttributeLockKeyMap();
        if(lockResultMap==null){
            lockResultMap=new HashMap<>();
            virtualDbLockInfoModel.setAttributeLockKeyMap(lockResultMap);
        }
        for (VirtualDbAttributeLockInfoModel tmpLockInfo:attributeLockInfolList){
            boolean tmpLocked=lockForOperate(tmpLockInfo.getLockKey());
            lockResultMap.put(tmpLockInfo.getLockKey(),tmpLocked);
            if(!tmpLocked){
                lockResultModel.setLocked(false);
                lockResultModel.setResultMsg(tmpLockInfo.getAttributeCode()+"="+tmpLockInfo.getAttributeValue()
                        +" lock failed");
                return lockResultModel;
            }
        }
        lockResultModel.setLocked(true);
        return lockResultModel;
    }

    private boolean lockForOperate(String key){
        return lockFunction.apply(key);
    }
}
